概述
ReentrantLock是java并发包中实现的可重入互斥锁,基于AQS实现,支持公平锁与非公平锁两种实现方式。公平锁是指当同步等待队列中有线程在排队获取锁时,新加入的准备获取锁的线程则加入同步等待队列尾;非公平锁是指新加入的准备获取锁的线程,不管同步等待队列中是否有线程正在排队,而直接先尝试获取锁,如果获取失败则加入同步等待队列尾。
内部类
ReentrantLock有三个内部类,其中Sync继承于AbstractQueuedSynchronizer;NonfairSync和FairSync则均继承于Sync分别用于实现非公平锁和公平锁。类依赖图如下所示:
Sync类
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();
/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// state == 0表示当前锁处于空闲状态,CAS操作修改state值,修改成功则表示获取锁成功
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 如果锁非空闲,但当前占有锁的线程即为当前线程本身,增加state的值,同样获得锁
// 这里说明ReentrantLock为可重入锁
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// c == 0 表示锁被当前线程完全释放,处于空闲状态
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
// Methods relayed from outer class
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
final boolean isLocked() {
return getState() != 0;
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
Sync类是NonfairSync和FairSync的基类,继承于AQS,其中实现了释放锁的操作以及非公平模式下尝试获取锁的操作。
NonfairSync类
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
// 非公平获取锁操作,
final void lock() {
// 不管是否有线程在排队获取锁,先直接CAS操作尝试修改state的值,修改成功则获得锁
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
实现非公平锁,在lock()操作中,不管是否有线程在排队,先尝试获取锁,如果获得成功则返回;否则调用acquire函数,该函数在AQS中实现,其功能为在将线程加入同步等待队列前,再次尝试获取锁,如果获取失败则将线程封装为Node节点加入同步等待队列并挂起,等待其前驱线程释放锁时唤醒。
FairSync类
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
final void lock() {
acquire(1);
}
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// 如果锁空闲,并且同步等待队列中无其他线程在排队,则尝试获取锁
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//当前占有锁的线程即为当前线程本身,增加state的值,同样获得锁(可重入)
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
实现公平锁,只有在同步等待队列中没有其他线程在排队时才尝试获取锁,否则直接加入同步等待队列尾。
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
hasQueuedPredecessors实现检查同步等待队列中是否有其他线程在排队,两种情况视为队列空:
(1)head == tail,即队列头尾指针指向同一个节点
(2)head.next != null && head.next.thread == Thread.currentThread(),队列中第一个节点为当前线程本身
构造函数
- public ReentrantLock() {sync = new NonfairSync();}
默认构造函数返回一个非公平锁
- public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}
带参数的构造函数,参数为true返回公平锁,参数为false返回非公平锁
常见方法
- public void lock();
获取锁
- public void unlock();
释放锁
- public Condition newCondition();
新建一个Condition对象